﻿using System;
using System.Collections.Generic;
using System.Linq;
using Autodesk.Revit.DB;

namespace YJKPatternSign.StairsClearHeightDimension
{
	public class CurveLoopSplit
	{
		public CurveLoopSplit(CurveLoop loop)
		{
			this.m_loop = loop;
			this.Init();
		}

		private void Init()
		{
			CurveArray curveArray = new CurveArray();
			CurveArray curveArray2 = new CurveArray();
			CurveLoopIterator curveLoopIterator = this.m_loop.GetCurveLoopIterator();
			while (curveLoopIterator.MoveNext())
			{
				Curve curve = curveLoopIterator.Current;
				Type type = curve.GetType();
				if (type == typeof(Line))
				{
					curveArray.Append(curve);
				}
				else if (type == typeof(Arc))
				{
					curveArray2.Append(curve);
				}
			}
			this.m_typeCurves.Add(CurveLoopSplit.CurveType.CT_LINE, curveArray);
			this.m_typeCurves.Add(CurveLoopSplit.CurveType.CT_ARC, curveArray2);
		}

		private void sortedCurveArray(CurveArray curves, out CurveArray sortCurves)
		{
			CurveArray curveArray = new CurveArray();
			SortedDictionary<double, CurveArray> sortedDictionary = new SortedDictionary<double, CurveArray>();
			CurveArrayIterator curveArrayIterator = curves.ForwardIterator();
			while (curveArrayIterator.MoveNext())
			{
				object obj = curveArrayIterator.Current;
				Curve curve = obj as Curve;
				if (curve != null)
				{
					double length = curve.Length;
					if (!sortedDictionary.ContainsKey(length))
					{
						CurveArray curveArray2 = new CurveArray();
						curveArray2.Append(curve);
						sortedDictionary.Add(length, curveArray2);
					}
					else
					{
						foreach (KeyValuePair<double, CurveArray> keyValuePair in sortedDictionary)
						{
							if (keyValuePair.Key == length)
							{
                                //SortedDictionary<double, CurveArray>.Enumerator enumerator;
                                //keyValuePair = enumerator.Current;
								keyValuePair.Value.Append(curve);
							}
						}
					}
				}
			}
			foreach (KeyValuePair<double, CurveArray> keyValuePair2 in sortedDictionary)
			{
				foreach (object obj2 in keyValuePair2.Value)
				{
					Curve curve2 = obj2 as Curve;
					if (null != curve2)
					{
						curveArray.Append(curve2);
					}
				}
			}
			sortCurves = curveArray;
		}

		public CurveArray GetCurves(CurveLoopSplit.CurveType type)
		{
			CurveArray result = null;
			switch (type)
			{
			case CurveLoopSplit.CurveType.CT_LINE:
				this.m_typeCurves.TryGetValue(type, out result);
				break;
			case CurveLoopSplit.CurveType.CT_ARC:
				this.m_typeCurves.TryGetValue(type, out result);
				break;
			}
			return result;
		}

		public CurveArray GetSortCurves(CurveLoopSplit.CurveType type)
		{
			CurveArray result = null;
			CurveArray curves = this.GetCurves(type);
			this.sortedCurveArray(curves, out result);
			return result;
		}

		public List<XYZ> GetCurvesPoint(CurveLoopSplit.CurveType type)
		{
			List<XYZ> list = new List<XYZ>();
			CurveArray curves = this.GetCurves(type);
			int size = curves.Size;
			for (int i = 0; i < size; i++)
			{
				Curve curve = curves.get_Item(i);
				list.Add(curve.GetEndPoint(0));
				list.Add(curve.GetEndPoint(1));
			}
			list.Distinct<XYZ>();
			return list;
		}

		public bool HasTwoArcCurve()
		{
			bool result = false;
			int num = 0;
			CurveLoopIterator curveLoopIterator = this.m_loop.GetCurveLoopIterator();
			while (curveLoopIterator.MoveNext())
			{
				if (curveLoopIterator.Current.GetType() == typeof(Arc))
				{
					num++;
				}
				if (2 == num)
				{
					result = true;
					break;
				}
			}
			return result;
		}

		public static List<Curve> GetCurveLoopCurves(CurveLoop loop)
		{
			List<Curve> list = new List<Curve>();
			foreach (Curve curve in loop)
			{
				if (null != curve)
				{
					list.Add(curve);
				}
			}
			return list;
		}

		private static XYZ GetArcMidPt(Arc arc)
		{
			List<XYZ> list = arc.Tessellate().ToList<XYZ>();
			int index = (list.Count - 1) / 2;
			return list.ElementAt(index);
		}

		private static List<Curve> CreateXYPlaneCurveloop(List<Curve> arCurve)
		{
			List<Curve> list = new List<Curve>();
			foreach (Curve curve in arCurve)
			{
				Type type = curve.GetType();
				if (type == typeof(Line))
				{
					Line line = curve as Line;
					if (null != line)
					{
						XYZ endPoint = line.GetEndPoint(0);
						XYZ endPoint2 = line.GetEndPoint(1);
						XYZ xyz = new XYZ(endPoint.X, endPoint.Y, 0.0);
						XYZ xyz2 = new XYZ(endPoint2.X, endPoint2.Y, 0.0);
						Line line2 = Line.CreateBound(xyz, xyz2);
						if (null != line2)
						{
							list.Add(line2);
						}
					}
				}
				else if (type == typeof(Arc))
				{
					Arc arc = curve as Arc;
					if (null != arc)
					{
						XYZ endPoint3 = arc.GetEndPoint(0);
						XYZ endPoint4 = arc.GetEndPoint(1);
						XYZ arcMidPt = CurveLoopSplit.GetArcMidPt(arc);
						if (arcMidPt != null)
						{
							XYZ xyz3 = new XYZ(endPoint3.X, endPoint3.Y, 0.0);
							XYZ xyz4 = new XYZ(endPoint4.X, endPoint4.Y, 0.0);
							XYZ xyz5 = new XYZ(arcMidPt.X, arcMidPt.Y, 0.0);
							Arc arc2 = Arc.Create(xyz3, xyz4, xyz5);
							if (null != arc2)
							{
								list.Add(arc2);
							}
						}
					}
				}
			}
			return list;
		}

		public static List<XYZ> GetCurveToLoopIntersection(Curve curve, CurveLoop loop)
		{
			List<XYZ> list = new List<XYZ>();
			foreach (Curve curve2 in CurveLoopSplit.CreateXYPlaneCurveloop(CurveLoopSplit.GetCurveLoopCurves(loop)))
			{
				IntersectionResultArray intersectionResultArray = null;
				curve.Intersect(curve2, out intersectionResultArray);
				if (intersectionResultArray != null && !intersectionResultArray.IsEmpty)
				{
					IntersectionResultArrayIterator intersectionResultArrayIterator = intersectionResultArray.ForwardIterator();
					while (intersectionResultArrayIterator.MoveNext())
					{
						object obj = intersectionResultArrayIterator.Current;
						IntersectionResult intersectionResult = obj as IntersectionResult;
						if (intersectionResult != null)
						{
							list.Add(intersectionResult.XYZPoint);
						}
					}
				}
			}
			return list;
		}

		private Dictionary<CurveLoopSplit.CurveType, CurveArray> m_typeCurves = new Dictionary<CurveLoopSplit.CurveType, CurveArray>();

		private CurveLoop m_loop = new CurveLoop();

		public enum CurveType
		{
			CT_LINE,
			CT_ARC,
			CT_ALL
		}
	}
}
